/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2002-2006 * Sleepycat Software. All rights reserved. * * $Id: DbSpace.java,v 1.1 2006/05/06 09:00:40 ckaestne Exp $ */ package com.sleepycat.je.util; import java.io.File; import java.io.PrintStream; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.SortedMap; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.DbInternal; import com.sleepycat.je.Environment; import com.sleepycat.je.EnvironmentConfig; import com.sleepycat.je.JEVersion; import com.sleepycat.je.cleaner.FileSummary; import com.sleepycat.je.cleaner.UtilizationProfile; import com.sleepycat.je.dbi.EnvironmentImpl; import com.sleepycat.je.utilint.CmdUtil; public class DbSpace { private static final String USAGE = "usage: " + CmdUtil.getJavaCommand(DbSpace.class) + "\n" + " -h <dir> # environment home directory\n" + " [-q] # quiet, print grand totals only\n" + " [-u] # sort by utilization\n" + " [-d] # dump file summary details\n" + " [-V] # print JE version number"; public static void main(String argv[]) throws DatabaseException { DbSpace space = new DbSpace(); space.parseArgs(argv); EnvironmentConfig envConfig = new EnvironmentConfig(); envConfig.setReadOnly(true); Environment env = new Environment(space.envHome, envConfig); space.envImpl = DbInternal.envGetEnvironmentImpl(env); try { space.print(System.out); System.exit(0); } catch (Throwable e) { e.printStackTrace(System.err); System.exit(1); } finally { try { env.close(); } catch (Throwable e) { e.printStackTrace(System.err); System.exit(1); } } } private File envHome = null; private EnvironmentImpl envImpl; private boolean quiet = false; private boolean sorted = false; private boolean details = false; private DbSpace() { } public DbSpace(Environment env, boolean quiet, boolean details, boolean sorted) { this(DbInternal.envGetEnvironmentImpl(env), quiet, details, sorted); } public DbSpace(EnvironmentImpl envImpl, boolean quiet, boolean details, boolean sorted) { this.envImpl = envImpl; this.quiet = quiet; this.details = details; this.sorted = sorted; } private void printUsage(String msg) { if (msg != null) { System.err.println(msg); } System.err.println(USAGE); System.exit(-1); } private void parseArgs(String argv[]) { int argc = 0; int nArgs = argv.length; if (nArgs == 0) { printUsage(null); System.exit(0); } while (argc < nArgs) { String thisArg = argv[argc++]; if (thisArg.equals("-q")) { quiet = true; } else if (thisArg.equals("-u")) { sorted = true; } else if (thisArg.equals("-d")) { details = true; } else if (thisArg.equals("-V")) { System.out.println(JEVersion.CURRENT_VERSION); System.exit(0); } else if (thisArg.equals("-h")) { if (argc < nArgs) { envHome = new File(argv[argc++]); } else { printUsage("-h requires an argument"); } } } if (envHome == null) { printUsage("-h is a required argument"); } } public void print(PrintStream out) throws DatabaseException { UtilizationProfile profile = envImpl.getUtilizationProfile(); SortedMap map = profile.getFileSummaryMap(false); int fileIndex = 0; Summary totals = new Summary(); Summary[] summaries = null; if (!quiet) { summaries = new Summary[map.size()]; } Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Long fileNum = (Long) entry.getKey(); FileSummary fs = (FileSummary) entry.getValue(); Summary summary = new Summary(fileNum, fs); if (summaries != null) { summaries[fileIndex] = summary; } if (details) { out.println("File 0x" + Long.toHexString(fileNum.longValue()) + ": " + fs); } totals.add(summary); fileIndex += 1; } if (details) { out.println(); } out.println(Summary.HEADER); if (summaries != null) { if (sorted) { Arrays.sort(summaries); } for (int i = 0; i < summaries.length; i += 1) { summaries[i].print(out); } } totals.print(out); } private static class Summary implements Comparable { static final String HEADER = " File Size (KB) % Used\n" + "-------- --------- ------"; // 12345678 123456789 123 // 12 12345 // TOTALS: Long fileNum; long totalSize; long obsoleteSize; Summary() { } Summary(Long fileNum, FileSummary summary) throws DatabaseException { this.fileNum = fileNum; totalSize = summary.totalSize; obsoleteSize = summary.getObsoleteSize(); } public int compareTo(Object other) { Summary o = (Summary) other; return utilization() - o.utilization(); } void add(Summary o) { totalSize += o.totalSize; obsoleteSize += o.obsoleteSize; } void print(PrintStream out) { if (fileNum != null) { pad(out, Long.toHexString(fileNum.longValue()), 8, '0'); } else { out.print(" TOTALS "); } int kb = (int) (totalSize / 1024); int util = utilization(); out.print(" "); pad(out, Integer.toString(kb), 9, ' '); out.print(" "); pad(out, Integer.toString(util), 3, ' '); out.println(); } int utilization() { return UtilizationProfile.utilization(obsoleteSize, totalSize); } private void pad(PrintStream out, String val, int digits, char padChar) { int padSize = digits - val.length(); for (int i = 0; i < padSize; i += 1) { out.print(padChar); } out.print(val); } } }